package com.ezlcp.user.config;

import com.alibaba.fastjson2.JSON;
import com.ezlcp.commons.base.entity.JsonResult;
import com.ezlcp.commons.exception.GetLockTimeoutException;
import com.ezlcp.user.service.LogService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Arrays;

/**
 * @author Elwin ZHANG
 * @description: 全局异常处理<br />
 * @date 2022/5/25 17:21
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @Lazy
    @Resource
    protected LogService logService;

    @ExceptionHandler(value = NullPointerException.class)
    public JsonResult exceptionHandler(HttpServletRequest req, NullPointerException e) {
        return writeLog(e, "common.nullPointer");
    }

    @ExceptionHandler(value = RuntimeException.class)
    public JsonResult exceptionHandler(HttpServletRequest req, RuntimeException e) {
        return writeLog(e, "common.runtime");
    }

    @ExceptionHandler(value = GetLockTimeoutException.class)
    public JsonResult exceptionHandler(HttpServletRequest req, GetLockTimeoutException e) {
        return writeLog(e, "common.lockTimeout");
    }

    @ExceptionHandler(value = Exception.class)
    public JsonResult exceptionHandler(HttpServletRequest req, Exception e) {
        return writeLog(e, "common.exception");
    }

    /***
     * @description 写错误日志到数据库
     * @param e 错误对象
     * @param name 异常名称
     * @author Elwin ZHANG
     * @date 2022/6/21 17:33
     */
    public JsonResult writeLog(Exception e, String name) {
        String message = e.getMessage();
        StackTraceElement[] stacks = e.getStackTrace();
        int index = stacks.length - 1;
        for (int i = index; i >= 0; i--) {
            String className = stacks[i].getClassName();
            if (className.startsWith("com.ezlcp")) {
                index = i;
            }
        }
        StackTraceElement[] newStacks = Arrays.copyOfRange(stacks, 0, index + 1);
        String stackTrace = JSON.toJSONString(newStacks);
        log.error(message, e);
        logService.saveSystemLog(name, null, "", message + ": " + stackTrace);
        JsonResult result = JsonResult.Fail(name);
        result.setDetailMsg(stackTrace);
        result.setData(message);
        return result;
    }
}